﻿using System;
using System.Threading;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
using HandyControl.Controls;
using WWLauncher.Command;
using WWLauncher.Constant;
using WWLauncher.Util;
using WWLauncher.ViewModel;
using ScrollViewer = System.Windows.Controls.ScrollViewer;
using TextBox = System.Windows.Controls.TextBox;

namespace WWLauncher.View.UserControls.PannelCard
{
    /// <summary>
    /// LeftCardControl.xaml 的交互逻辑
    /// </summary>
    public partial class LeftCardControl : UserControl
    {
        private int menuSelectIndexTemp = -1;
        private readonly MainViewModel mainViewModel = MainViewModel.Instance();
        private readonly AppConfig config = MainViewModel.Instance().AppConfig;
        private readonly SolidColorBrush bac = new(Color.FromRgb(255, 255, 255));
        public MainWindow ParentWindow { get; set; }
        public LeftCardControl()
        {
            InitializeComponent();

            this.Loaded += (s, e) =>
            {
                bac.Opacity = 0.6;
                SelectLastMenu();
                SetMenuListBoxItemEvent();
                MenuListBox.SelectionChanged += Menu_SelectionChanged;
            };

        }

        private void SetMenuListBoxItemEvent()
        {
            int size = MenuListBox.Items.Count;
            for (var i = 0; i < size; i++)
            {
                ListBoxItem lbi = (ListBoxItem)(MenuListBox.ItemContainerGenerator.ContainerFromIndex(i));
                if (lbi != null)
                {
                    SetListBoxItemEvent(lbi);
                }
            }
            MenuListBox.UpdateLayout();
            //首次触发不了Selected事件
            object obj = MenuListBox.ItemContainerGenerator.ContainerFromIndex(MenuListBox.SelectedIndex);
            if (obj != null)
                Lbi_Selected(obj, null);
        }

        private void SetListBoxItemEvent(ListBoxItem lbi)
        {
            lbi.MouseEnter += (s, me) =>
            {
                lbi.Background = bac;
            };
            lbi.Unselected += Lbi_Unselected;

            lbi.MouseLeave += Lbi_MouseLeave;

            lbi.Selected += Lbi_Selected;
        }

        private void SelectLastMenu()
        {
            if (mainViewModel.SelectedMenuIndex >= mainViewModel.MenuList.Count || mainViewModel.SelectedMenuIndex == -1)
            {
                MenuListBox.SelectedIndex = 0;
                mainViewModel.SelectedMenuIndex = MenuListBox.SelectedIndex;
                mainViewModel.SelectedMenuIcons = mainViewModel.MenuList[0].IconList;
            }
            else
            {
                MenuListBox.SelectedIndex = mainViewModel.SelectedMenuIndex;
                if (!mainViewModel.MenuList[mainViewModel.SelectedMenuIndex].IsEncrypt)
                    mainViewModel.SelectedMenuIcons = mainViewModel.MenuList[mainViewModel.SelectedMenuIndex].IconList;
                else
                    mainViewModel.SelectedMenuIcons = null;
            }
        }

        private DelegateCommand<int[]> swap;

        public DelegateCommand<int[]> SwapCommand
        {
            get
            {
                if (swap == null)
                    swap = new DelegateCommand<int[]>(
                        (indexes) =>
                        {
                            int fromS = indexes[0];
                            int to = indexes[1];
                            var menuList = mainViewModel.MenuList;
                            var dragged = menuList[fromS];
                            menuList.Remove(dragged);
                            menuList.Insert(to, dragged);
                            MenuListBox.SelectedIndex = to;
                            mainViewModel.MenuList = menuList;
                        }
                    );
                return swap;
            }
        }


        /// <summary>
        /// 当修改菜单元素可见时 设置原菜单为不可见 并且不可选中
        /// 修改菜单元素不可见时  原菜单可见 并 选中
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void MenuWhenVisibilityChanged(object sender, DependencyPropertyChangedEventArgs e)
        {
            StackPanel sp = sender as StackPanel;

            ListBoxItem lbi = (sp.TemplatedParent as ContentPresenter).TemplatedParent as ListBoxItem;
            if (sp.Visibility == Visibility.Collapsed)
            {
                lbi.MouseEnter += Lbi_MouseEnter;
                if (MenuListBox.SelectedIndex != -1)
                {
                    menuSelectIndexTemp = MenuListBox.SelectedIndex;
                    MenuListBox.SelectedIndex = -1;
                }
                else
                {
                    MenuListBox.SelectedIndex = menuSelectIndexTemp;
                }
            }
            else
            {
                lbi.MouseEnter += (s, me) =>
                {
                    lbi.Background = bac;
                };

                lbi.MouseLeave += Lbi_MouseLeave;
                lbi.Selected += Lbi_Selected;
            }
        }

        #region 设置菜单触发事件
        private void Lbi_MouseEnter(object sender, MouseEventArgs e)
        {
            ListBoxItem lbi = sender as ListBoxItem;
            lbi.Background = Brushes.Transparent;
        }

        private void Lbi_Unselected(object sender, RoutedEventArgs e)
        {
            //添加Leave效果
            ListBoxItem lbi = sender as ListBoxItem;
            lbi.Background = Brushes.Transparent;
            lbi.MouseLeave += Lbi_MouseLeave;
        }

        private void Lbi_Selected(object sender, RoutedEventArgs e)
        {
            ListBoxItem lbi = sender as ListBoxItem;

            SolidColorBrush fontColor = new SolidColorBrush(Colors.Black);

            lbi.MouseLeave -= Lbi_MouseLeave;
            lbi.Background = bac;
            lbi.Foreground = fontColor;
        }

        private void Lbi_MouseLeave(object sender, MouseEventArgs e)
        {
            ListBoxItem lbi = sender as ListBoxItem;
            lbi.Background = Brushes.Transparent;
        }
        #endregion

        /// <summary>
        /// 新建菜单
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void CreateMenu_Click(object sender, RoutedEventArgs e)
        {
            MenuViewModel info = new MenuViewModel() { MenuEdit = Visibility.Collapsed, MenuId = System.Guid.NewGuid().ToString(), MenuName = "新建菜单" };
            mainViewModel.MenuList.Add(info);
            MenuListBox.SelectedIndex = mainViewModel.MenuList.Count - 1;
            mainViewModel.SelectedMenuIndex = MenuListBox.SelectedIndex;
            mainViewModel.SelectedMenuIcons = info.IconList;
            MenuListBox.UpdateLayout();
            //首次触发不了Selected事件
            object obj = MenuListBox.ItemContainerGenerator.ContainerFromIndex(MenuListBox.SelectedIndex);
            SetListBoxItemEvent((ListBoxItem)obj);
            Lbi_Selected(obj, null);
        }


        /// <summary>
        /// 重命名菜单 将textbox 设置为可见
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void RenameMenu_Click(object sender, RoutedEventArgs e)
        {
            RunTimeStatus.IsMenuEdit = true;
            var menuInfo = ((MenuItem)sender).Tag as MenuViewModel;
            menuInfo.MenuEdit = (int)Visibility.Visible;
        }

        /// <summary>
        /// 删除菜单
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void DeleteMenu_Click(object sender, RoutedEventArgs e)
        {

            MenuViewModel menuInfo = ((MenuItem)sender).Tag as MenuViewModel;
            if (menuInfo is { IconList.Count: > 0 })
            {
                Growl.Ask("确认删除此菜单吗?", isConfirmed =>
                {
                    if (isConfirmed)
                    {
                        DeleteMenu_Click(menuInfo);
                    }
                    return true;
                }, "MainWindowAskGrowl");
            }
            else
            {
                DeleteMenu_Click(menuInfo);
            }
        }

        private void DeleteMenu_Click(MenuViewModel menuInfo)
        {
            if (mainViewModel.MenuList.Count == 1)
            {
                //如果删除以后没有菜单的话 先创建一个
                CreateMenu_Click(null, null);
            }
            int index = mainViewModel.MenuList.IndexOf(menuInfo);
            if (index == 0)
            {
                index = 0;
            }
            else
            {
                index--;
            }

            mainViewModel.MenuList.Remove(menuInfo);
            // 选中下一个菜单
            MenuListBox.SelectedIndex = index;
            mainViewModel.SelectedMenuIndex = MenuListBox.SelectedIndex;
            mainViewModel.SelectedMenuIcons = mainViewModel.MenuList[index].IconList;
        }

        /// <summary>
        /// 编辑菜单失焦或者敲下Enter键时保存修改后的菜单
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void LostFocusOrEnterDown(object sender, EventArgs e)
        {
            bool done = true;
            TextBox menuBox = null;
            if (e.GetType() == typeof(KeyEventArgs))
            {
                if (e is KeyEventArgs { Key: Key.Enter } eKey)
                {
                    menuBox = ((TextBox)sender);
                }
                else
                {
                    done = false;
                }
            }
            else if (e.GetType() == typeof(RoutedEventArgs))
            {
                menuBox = ((TextBox)sender);
            }

            if (done)
            {
                if (menuBox != null)
                {
                    MenuViewModel menuInfo = menuBox.Tag as MenuViewModel;
                    var text = menuBox.Text;
                    if (menuInfo != null)
                    {
                        menuInfo.MenuName = text;
                        menuInfo.MenuEdit = Visibility.Collapsed;
                    }
                }
                RunTimeStatus.IsMenuEdit = false;
                //为了解决无法修改菜单的问题
                ParentWindow.SearchBox.Focus();
                MenuListBox.SelectedIndex = menuSelectIndexTemp;
            }
        }

        /// <summary>
        /// 当修改菜单元素可见时 设置全选并获得焦点
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void MenuEditWhenVisibilityChanged(object sender, DependencyPropertyChangedEventArgs e)
        {
            if (sender is TextBox { Visibility: Visibility.Visible } box)
            {
                Keyboard.Focus(box);
                box.SelectAll();
            }
        }

        /// <summary>
        /// 修改菜单图标
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void EditMenuGeometry_Click(object sender, RoutedEventArgs e)
        {
            MenuViewModel menuInfo = ((MenuItem)sender).Tag as MenuViewModel;
            IconfontWindow.Show(menuInfo);
        }

        private void Menu_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            if (RunTimeStatus.IsMenuEdit) return;

            if (config.ItemSpradeAnimation)
            {
                //是否启用列表展开动画
                ParentWindow.RightCard.WrapUFG.Visibility = Visibility.Collapsed;
            }

            //设置对应菜单的图标列表
            if (MenuListBox.SelectedIndex == -1)
            {
                //config.SelectedMenuIcons = appData.MenuList[appData.MenuList.Count - 1].IconList;
            }
            else
            {
                if (mainViewModel.MenuList[MenuListBox.SelectedIndex].IsEncrypt)
                {
                    mainViewModel.SelectedMenuIcons = null;
                    RunTimeStatus.ShowMenuPasswordbox = true;
                    ParentWindow.RightCard.PDDialog.Title.Text = "输入密码";
                    ParentWindow.RightCard.PDDialog.type = PasswordType.Input;
                    ParentWindow.RightCard.PDDialog.Visibility = Visibility.Visible;
                }
                else
                {
                    ParentWindow.RightCard.PDDialog.Visibility = Visibility.Collapsed;
                    mainViewModel.SelectedMenuIcons = mainViewModel.MenuList[MenuListBox.SelectedIndex].IconList;
                }
            }
            ParentWindow.RightCard.WrapUFG.Visibility = Visibility.Visible;
            //App.DoEvents();
        }


        /// <summary>
        /// 鼠标悬停切换菜单
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Menu_MouseEnter(object sender, MouseEventArgs e)
        {
            if (config.HoverMenu && !RunTimeStatus.IsMenuEdit)
            {
                Thread t = new Thread(() =>
                {
                    Thread.Sleep(200);
                    this.Dispatcher.Invoke(() =>
                    {
                        if (sender is ListBoxItem { IsMouseOver: true } lbi)
                        {
                            int index = MenuListBox.ItemContainerGenerator.IndexFromContainer(lbi);
                            MenuListBox.SelectedIndex = index;
                        }
                    });
                });
                t.IsBackground = true;
                t.Start();
            }
        }

        /// <summary>
        /// 点击菜单后  隐藏搜索框
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void ListBoxItem_MouseDown(object sender, MouseButtonEventArgs e)
        {
            if (RunTimeStatus.SearchBoxShow)
            {
                ParentWindow.HidedSearchBox();
            }

            ListBoxItem lbi = sender as ListBoxItem;
            MenuViewModel mi = lbi.DataContext as MenuViewModel;
            int index = MenuListBox.Items.IndexOf(mi);
            MenuListBox.SelectedIndex = index;
        }


        /// <summary>
        /// 隐藏搜索框
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void MyCard_MouseDown(object sender, MouseButtonEventArgs e)
        {
            if (RunTimeStatus.SearchBoxShow)
            {
                ParentWindow.HidedSearchBox();
            }
        }

        private void Menu_MouseWheel(object sender, MouseWheelEventArgs e)
        {
            if (RunTimeStatus.IsMenuEdit) return;

            var scrollViewer = ScrollUtil.FindSimpleVisualChild<ScrollViewer>(MenuListBox);
            if (e.Delta < 0)
            {
                //判断是否到了最底部
                if (ScrollUtil.IsBootomScrollView(scrollViewer))
                {
                    int index = MenuListBox.SelectedIndex;
                    if (index < MenuListBox.Items.Count - 1)
                    {
                        index++;
                    }
                    else
                    {
                        index = 0;
                    }
                    MenuListBox.SelectedIndex = index;
                }
            }
            else if (e.Delta > 0)
            {
                if (ScrollUtil.IsTopScrollView(scrollViewer))
                {
                    int index = MenuListBox.SelectedIndex;
                    if (index > 0)
                    {
                        index--;
                    }
                    else
                    {
                        index = MenuListBox.Items.Count - 1;
                    }
                    MenuListBox.SelectedIndex = index;
                }
            }

            //滚动到选中项
            MenuListBox.ScrollIntoView(MenuListBox.SelectedItem);
        }


        private void Menu_PreviewDragLeave(object sender, DragEventArgs e)
        {
            MyPoptip.IsOpen = false;
        }

        private void Menu_PreviewDragEnter(object sender, DragEventArgs e)
        {
            MenuViewModel mi = (sender as ListBoxItem)?.DataContext as MenuViewModel;
            MyPoptipContent.Text = "移动至：" + mi.MenuName;
            MyPoptip.VerticalOffset = 30;
            MyPoptip.IsOpen = true;
        }

        private void Menu_MouseLeave(object sender, MouseEventArgs e)
        {
            MyPoptip.IsOpen = false;
        }

        /// <summary>
        /// 拖拽移动图标到指定菜单
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Menu_Drop(object sender, DragEventArgs e)
        {
            MyPoptip.IsOpen = false;

            MenuViewModel mi = (sender as ListBoxItem)?.DataContext as MenuViewModel;
            IconInfo iconInfo = (IconInfo)e.Data.GetData(typeof(IconInfo));
            if (iconInfo != null)
            {
                // 将已有图标移动到该菜单
                mainViewModel.MenuList[MenuListBox.SelectedIndex].IconList.Remove(iconInfo);
                mainViewModel.MenuList[MenuListBox.Items.IndexOf(mi)].IconList.Add(iconInfo);

            }
            else
            {
                // 直接将新图标移动到该菜单
                Array dropObject = (System.Array)e.Data.GetData(DataFormats.FileDrop);
                if (dropObject == null) return;
                foreach (object obj in dropObject)
                {
                    string path = (string)obj;
                    iconInfo = CommonCode.GetIconInfoByPath(path).To();
                    if (iconInfo == null)
                    {
                        LogUtil.WriteLog("添加项目失败，未能获取到项目图标：" + path);
                        break;

                    }
                    mainViewModel.MenuList[MenuListBox.Items.IndexOf(mi)].IconList.Add(iconInfo);
                }
                CommonCode.SortIconList();
                ConfigUtil.SaveAppData();
            }
        }

        private void EncryptMenu(object sender, RoutedEventArgs e)
        {

            MenuViewModel menuInfo = ((MenuItem)sender).Tag as MenuViewModel;


            if (menuInfo.IsEncrypt)
            {
                menuInfo.IsEncrypt = false;
                RunTimeStatus.ShowMenuPasswordbox = false;
                ParentWindow.RightCard.PDDialog.Visibility = Visibility.Hidden;
                SelectLastMenu();

            }
            else
            {
                if (string.IsNullOrEmpty(config.MenuPassword))
                {
                    ParentWindow.RightCard.PDDialog.menuInfo = menuInfo;
                    ParentWindow.RightCard.PDDialog.Title.Text = "设置新密码";
                    ParentWindow.RightCard.PDDialog.type = PasswordType.Create;
                    RunTimeStatus.ShowMenuPasswordbox = true;
                    ParentWindow.RightCard.PDDialog.Visibility = Visibility.Visible;
                }
                else
                {
                    menuInfo.IsEncrypt = true;
                    Growl.Success(menuInfo.MenuName + " 已加密!", "MainWindowGrowl");
                }
            }
        }

        private void AlterPassword_Click(object sender, RoutedEventArgs e)
        {
            ParentWindow.RightCard.PDDialog.Title.Text = "输入旧密码";
            ParentWindow.RightCard.PDDialog.type = PasswordType.Alter;
            ParentWindow.RightCard.PDDialog.Visibility = Visibility.Visible;
            //单独设置焦点
            ParentWindow.RightCard.PDDialog.SetFocus();
        }

        /// <summary>
        /// 右键点击进行处理 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void MyCard_PreviewMouseRightButtonDown(object sender, MouseButtonEventArgs e)
        {
            RunTimeStatus.ShowRightBtnMenu = true;
            new Thread(() =>
            {
                Thread.Sleep(50);
                RunTimeStatus.ShowRightBtnMenu = false;
            }).Start();

            //在没有设置密码的情况下不弹出修改密码菜单
            if (string.IsNullOrEmpty(config.MenuPassword))
            {
                AlterPW1.Visibility = Visibility.Collapsed;
            }
            else
            {
                AlterPW1.Visibility = Visibility.Visible;
            }
        }

        private void ListBoxItem_PreviewMouseRightButtonDown(object sender, MouseButtonEventArgs e)
        {
            ListBoxItem lbi = sender as ListBoxItem;
            MenuViewModel info = lbi.DataContext as MenuViewModel;

            ItemCollection ics = lbi.ContextMenu.Items;

            foreach (object obj in ics)
            {
                MenuItem mi = (MenuItem)obj;
                if (mi.Header.Equals("修改密码"))
                {
                    if (string.IsNullOrEmpty(config.MenuPassword))
                    {
                        mi.Visibility = Visibility.Collapsed;
                    }
                    else
                    {
                        mi.Visibility = Visibility.Visible;
                    }
                    break;
                }
                if (mi.Header.Equals("加密此列表") || mi.Header.Equals("取消加密此列表"))
                {
                    if (info.IsEncrypt)
                    {
                        mi.Header = "取消加密此列表";
                    }
                    else
                    {
                        mi.Header = "加密此列表";
                    }
                }
            }

        }


    }
}
